package com.opal.jx.service.impl;

import com.opal.consts.WSC;
import com.opal.domain.R;
import com.opal.jx.JxConst.JxConst;
import com.opal.jx.entity.JxAssessReception;
import com.opal.jx.entity.table.*;
import com.opal.jx.exception.JxAssessException;
import com.opal.jx.mapper.mysql.JxAssessPzcjMapper;
import com.opal.jx.service.JxAssessTotalService;
import com.opal.jx.service.JxEmpService;
import com.opal.jx.service.JxPZCJService;
import com.opal.jx.service.JxPostService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class JxPZCJServiceImpl implements JxPZCJService {
    @Autowired
    private JxAssessPzcjMapper jxAssessPzcjMapper;
    @Autowired
    private JxEmpService jxEmpService;
    @Autowired
    private JxPostService jxPostService;
    @Autowired
    @Qualifier("JxAssessPzcjTotalServiceImpl")
    private JxAssessTotalService jxAssessTotalService;

    @Override
    @Transactional("mysqlTransactionManager")
    public R addKaiLiaoYuanAssessDataService(JxAssessReception jxAssessPzcjReception) {

        //判断提交数据
        isSubmitData(jxAssessPzcjReception);
        //插入开料员绩效数据
        List<JxAssessPzcj> jxAssessPzcjs = addKaiLiaoYuanAssessDataGetJxAssessPzcjs(jxAssessPzcjReception, JxConst.ASSESSTYPE_KAILIAOYUAN,JxConst.ASSESSTYPE_KAILIAOGUANLIRENYUAN);

        //获取管理人员信息
        List<JxEmp> jxEmps = addKaiLiaoYuanAssessDataGetJxEmps(jxAssessPzcjs,JxConst.KAILIAOGUANLIRENYUAN);

        //往绩效表插入管理人员初始化的数据
        addKaiLiaoYuanAssessDataAddManagerData(jxAssessPzcjReception, jxAssessPzcjs, jxEmps,JxConst.ASSESSTYPE_KAILIAOGUANLIRENYUAN);


        return new R(WSC.RESTPONSE_OK, JxConst.SUBMIT_SUCCESS);
    }

    @Override
    @Transactional("mysqlTransactionManager")
    public R addNewKaiLiaoYuanAssessDataService(JxAssessReception jxAssessPzcjReception) {
        //1、判断提交数据
        isSubmitData(jxAssessPzcjReception);
        //2、插入新开料员绩效数据
        List<JxAssessPzcj> jxAssessPzcjs = addKaiLiaoYuanAssessDataGetJxAssessPzcjs(jxAssessPzcjReception,
                JxConst.ASSESSTYPE_NEWKAILIAOYUAN,JxConst.ASSESSTYPE_PEIXUNZUZHANG);
        //3、获取培训组长的信息
        List<JxEmp> jxEmps = addKaiLiaoYuanAssessDataGetJxEmps(jxAssessPzcjs,JxConst.PEIXUNZUZHANG);
        //4、往绩效表插入培训组长的初始化的数据
        addKaiLiaoYuanAssessDataAddManagerData(jxAssessPzcjReception, jxAssessPzcjs, jxEmps,JxConst.ASSESSTYPE_PEIXUNZUZHANG);

        return new R(WSC.RESTPONSE_OK, JxConst.SUBMIT_SUCCESS);
    }

    @Override
    @Transactional("mysqlTransactionManager")
    public R addManagersAssessDataService(JxAssessReception jxAssessPzcjReception) {
        //判断数据
        isSubmitData(jxAssessPzcjReception);
        //删除组长、主管的绩效奖金和最终绩效奖金合计表中的数据:防止重复性
        List<JxAssessPzcj> jxAssessPzcjs = jxAssessPzcjReception.getJxAssessPzcjs();
        Integer month = jxAssessPzcjs.get(0).getAssessMonth();
        Integer year = jxAssessPzcjs.get(0).getAssessYear();
        deleteJxAssessPzcjEmp(JxConst.ASSESSTYPE_KAILIAOGUANLIRENYUAN,year,month);
        //往绩效表中插入组长、主管绩效数据
        jxAssessPzcjs.stream().forEach(jx->{
            String resultMoney = jx.getResultMoney();
            if (StringUtils.isBlank(resultMoney)){
                throw new JxAssessException(WSC.PRECONDITIONFAILED, JxConst.SUBMIT_EFEATED_RWAULTMONEY_NULL_DATA);
            }else if(resultMoney.equals("NaN")){
                throw new JxAssessException(WSC.PRECONDITIONFAILED, JxConst.SUBMIT_EFEATED_NULL_DATA);
            }
            jx.setAssessType(JxConst.ASSESSTYPE_KAILIAOGUANLIRENYUAN); //3、管理人员表的考核资料、
            this.addJxAssessPzcj(jx);
        });

        //保存最终综合绩效奖金统计
        this.addJxAssessTotal(jxAssessPzcjReception,month,year,JxConst.ASSESSTYPE_KAILIAOGUANLIRENYUAN);

        return new R(WSC.RESTPONSE_OK, JxConst.SUBMIT_SUCCESS);
    }

    @Override
    @Transactional("mysqlTransactionManager")
    public R addFuZhuRenYuanAssessDataService(JxAssessReception jxAssessPzcjReception) {
        isSubmitData(jxAssessPzcjReception);
        List<JxAssessPzcj> jxAssessPzcjs = jxAssessPzcjReception.getJxAssessPzcjs();
        Integer month = jxAssessPzcjs.get(0).getAssessMonth();
        Integer year = jxAssessPzcjs.get(0).getAssessYear();
        //清空当月辅助人员的数据
        deleteJxAssessPzcjEmp(JxConst.ASSESSTYPE_FUZHURENYUAN,year,month);
        //添加辅助人员的信息
        jxAssessPzcjs.stream().forEach(jx-> {

            String resultMoney = jx.getResultMoney();
            if (resultMoney.equals("NaN")) {
                throw new JxAssessException(WSC.PRECONDITIONFAILED, JxConst.SUBMIT_EFEATED_ILLEGALITY_DATA);
            }
            jx.setAssessType(JxConst.ASSESSTYPE_FUZHURENYUAN);
            this.addJxAssessPzcj(jx);
        });
        //保存最终综合绩效奖金统计
        this.addJxAssessTotal(jxAssessPzcjReception,month,year,JxConst.ASSESSTYPE_FUZHURENYUAN);
        return new R(WSC.RESTPONSE_OK, JxConst.SUBMIT_SUCCESS);
    }

    @Override
    @Transactional("mysqlTransactionManager")
    public R addPeiXunZuZhangAssessDataService(JxAssessReception jxAssessPzcjReception) {
        //判断数据
        isSubmitData(jxAssessPzcjReception);
        //删除培训组长当年当月的绩效奖金:防止重复性
        List<JxAssessPzcj> jxAssessPzcjs = jxAssessPzcjReception.getJxAssessPzcjs();
        Integer month = jxAssessPzcjs.get(0).getAssessMonth();
        Integer year = jxAssessPzcjs.get(0).getAssessYear();
        deleteJxAssessPzcjEmp(JxConst.ASSESSTYPE_PEIXUNZUZHANG,year,month);
        //往绩效表中插入培训组长的绩效数据
        jxAssessPzcjs.stream().forEach(jx->{
            String resultMoney = jx.getResultMoney();
            if (StringUtils.isBlank(resultMoney)){
                throw new JxAssessException(WSC.PRECONDITIONFAILED, JxConst.SUBMIT_EFEATED_RWAULTMONEY_NULL_DATA);
            }else if(resultMoney.equals("NaN")){
                throw new JxAssessException(WSC.PRECONDITIONFAILED, JxConst.SUBMIT_EFEATED_NULL_DATA);
            }
            jx.setAssessType(JxConst.ASSESSTYPE_PEIXUNZUZHANG); //培训组长的类型绩效数据
            this.addJxAssessPzcj(jx);
        });

        //保存最终综合绩效奖金统计
        this.addJxAssessTotal(jxAssessPzcjReception,month,year,JxConst.ASSESSTYPE_PEIXUNZUZHANG);

        return new R(WSC.RESTPONSE_OK, JxConst.SUBMIT_SUCCESS);
    }

    @Override
    public R addChengLiaoAssessDataService(JxAssessReception jxAssessPzcjReception) {
        //判断数据
        isSubmitData(jxAssessPzcjReception);
        //删除称料房主管当年当月的绩效奖金:防止重复性
        List<JxAssessPzcj> jxAssessPzcjs = jxAssessPzcjReception.getJxAssessPzcjs();
        Integer month = jxAssessPzcjs.get(0).getAssessMonth();
        Integer year = jxAssessPzcjs.get(0).getAssessYear();
        deleteJxAssessPzcjEmp(JxConst.ASSESSTYPE_CHENGLIAOFANGZHUGUAN,year,month);
        //往绩效表中插入培训组长的绩效数据
        jxAssessPzcjs.stream().forEach(jx->{
            String resultMoney = jx.getResultMoney();
            if (StringUtils.isBlank(resultMoney)){
                throw new JxAssessException(WSC.PRECONDITIONFAILED, JxConst.SUBMIT_EFEATED_RWAULTMONEY_NULL_DATA);
            }else if(resultMoney.equals("NaN")){
                throw new JxAssessException(WSC.PRECONDITIONFAILED, JxConst.SUBMIT_EFEATED_NULL_DATA);
            }
            jx.setAssessType(JxConst.ASSESSTYPE_CHENGLIAOFANGZHUGUAN); //称料房的类型的数据
            this.addJxAssessPzcj(jx);
        });
        //保存最终综合绩效奖金统计
        addJxAssessTotal(jxAssessPzcjReception, month, year,JxConst.ASSESSTYPE_CHENGLIAOFANGZHUGUAN);
        return new R(WSC.RESTPONSE_OK, JxConst.SUBMIT_SUCCESS);
    }

    @Override
    public JxAssessPzcj selectJxAssessPzcjById(String id) {
        JxAssessPzcj jxAssessPzcj = jxAssessPzcjMapper.selectByPrimaryKey(id);
        return jxAssessPzcj;
    }

    @Override
    public List<JxAssessPzcj> selectJxAssessPzcjByCondition(JxAssessPzcj condition) {
        JxAssessPzcjExample jxAssessPzcjExample=this.getJxAssessPzcjExample(condition);
        if (jxAssessPzcjExample ==null){
            return null;
        }
        List<JxAssessPzcj> jxAssessPzcjStaffs = jxAssessPzcjMapper.selectByExample(jxAssessPzcjExample);
        return jxAssessPzcjStaffs;
    }



    @Override
    public Integer addJxAssessPzcj(JxAssessPzcj jxAssessPzcj) {
        return jxAssessPzcjMapper.insertSelective(jxAssessPzcj);
    }

    @Override
    public Integer deleteJxAssessPzcjByCondition(JxAssessPzcj condition) {
        JxAssessPzcjExample jxAssessPzcjExample = this.getJxAssessPzcjExample(condition);
        if (jxAssessPzcjExample ==null){
            return -1;
        }
        int i = jxAssessPzcjMapper.deleteByExample(jxAssessPzcjExample);
        return i ;
    }

    @Override
    public Integer updateJxAssessPzcjByCondition(JxAssessPzcj jxAssessPzcj, JxAssessPzcj condition) {
        JxAssessPzcjExample jxAssessPzcjManagerExample = this.getJxAssessPzcjExample(condition);
        int i = jxAssessPzcjMapper.updateByExampleSelective(jxAssessPzcj, jxAssessPzcjManagerExample);

        return i ;
    }

    @Override
    public List<JxAssessPzcj> selectJxAssessPzcjByCondition(Integer year, Integer month, String... postNames) {
        JxAssessPzcjExample jxAssessPzcjExample = new JxAssessPzcjExample();
        JxAssessPzcjExample.Criteria criteria = jxAssessPzcjExample.createCriteria().andAssessYearEqualTo(year).andAssessMonthEqualTo(month);
        if (postNames !=null && postNames.length>0){
            criteria.andPostNameIn(Arrays.asList(postNames));
        }
        List<JxAssessPzcj> jxAssessPzcjs = jxAssessPzcjMapper.selectByExample(jxAssessPzcjExample);

        return jxAssessPzcjs;
    }

    private JxAssessPzcjExample getJxAssessPzcjExample(JxAssessPzcj condition) {

        if (condition !=null){
            JxAssessPzcjExample jxAssessPzcjExample=new JxAssessPzcjExample();
            JxAssessPzcjExample.Criteria criteria = jxAssessPzcjExample.createCriteria();
            String empCode = condition.getEmpCode();                //员工工号
            String empName = condition.getEmpName();                //员工姓名
            Integer assessYear = condition.getAssessYear();         //考核年份
            Integer assessMonth = condition.getAssessMonth();       //考核月份
            String postName = condition.getPostName();              //岗位名称
            String assessDept = condition.getAssessDept();          //部门
            String empGroup = condition.getEmpGroup();              //班组：A、B、C、D.......
            String empNew = condition.getEmpNew();                  //是否新员工：是/否，默认 "否"；
            Integer assessType = condition.getAssessType();         //有时候不单单是本职位的就是做本职位工作，1、开料员绩效考核资料，2、新开料员表绩效考核资料、3、管理人员表的考核资料、4、辅助人员表的考核资料、5：培训组长的表考核资料、6、称料房主管表中的考核资料
            if (!StringUtils.isBlank(empCode)){
                criteria.andEmpCodeEqualTo(empCode);
            }
            if (!StringUtils.isBlank(empName)){
                criteria.andEmpNameEqualTo(empName);
            }
            if (assessType !=null){
                criteria.andAssessTypeEqualTo(assessType);
            }
            if (assessYear !=null){
                criteria.andAssessYearEqualTo(assessYear);
            }
            if (assessMonth !=null){
                criteria.andAssessMonthEqualTo(assessMonth);
            }
            if (!StringUtils.isBlank(postName)){
                criteria.andPostNameEqualTo(postName);
            }
            if (!StringUtils.isBlank(assessDept)){
                criteria.andAssessDeptEqualTo(assessDept);
            }
            if (!StringUtils.isBlank(empGroup)){
                criteria.andEmpGroupEqualTo(empGroup);
            }
            if (!StringUtils.isBlank(empNew)){
                criteria.andEmpGroupEqualTo(empNew);
            }
            return jxAssessPzcjExample;
        }
        return null;
    }


    //根据报表类型删除操作
    private void   deleteJxAssessPzcjEmp(Integer assessType,Integer year,Integer month){
        if (assessType==null){
            log.error("表类型assessType没有值，删除失败.....这种情况会造成重新提交会造成当月有重复的绩效数据发生");
        }
        //去除条件：姓名、员工工号、组别
        JxAssessPzcj jxAssessPzcj= new JxAssessPzcj();
        jxAssessPzcj.setAssessType(assessType);
        jxAssessPzcj.setAssessYear(year);
        jxAssessPzcj.setAssessMonth(month);
        this.deleteJxAssessPzcjByCondition(jxAssessPzcj);
        //删除绩效奖金总合计表中的数据：年、月、绩效类型
        JxAssessTotal jxAssessTotal = new JxAssessTotal();
        jxAssessTotal.setAssessMonth(month);
        jxAssessTotal.setAssessYear(year);
        jxAssessTotal.setAssessType(assessType);
        jxAssessTotalService.deleteByExample(jxAssessTotal);
    }

    //判断前端提交数据
    private void  isSubmitData(JxAssessReception jxAssessPzcjReception){
        //判断数据是否有效
        List<JxAssessPzcj> jxAssessPzcjs = jxAssessPzcjReception.getJxAssessPzcjs();
        if (jxAssessPzcjs.size()<=0){
            throw new JxAssessException(WSC.PRECONDITIONFAILED, JxConst.SUBMIT_EFEATED_NULL_DATA);
        }
    }

    //封装年、月、部门数据
    private JxAssessPzcj packagingJxAssessPzcj(List<JxAssessPzcj> jxAssessPzcjs){
        JxAssessPzcj jx= new JxAssessPzcj();
        jx.setAssessDept(jxAssessPzcjs.get(0).getAssessDept());     //封装部门
        jx.setAssessMonth(jxAssessPzcjs.get(0).getAssessMonth());   //封装月
        jx.setAssessYear(jxAssessPzcjs.get(0).getAssessYear());     //年
        return jx;
    }

    @NotNull
    private List<JxAssessPzcj> addKaiLiaoYuanAssessDataGetJxAssessPzcjs(JxAssessReception jxAssessPzcjReception, Integer assessType, Integer assessType2) {
        //获取开料员绩效奖金对象
        List<JxAssessPzcj> jxAssessPzcjs = jxAssessPzcjReception.getJxAssessPzcjs();
        // 根据年月条件删除现有的数据：保证本月份数据不重复性(本方法是一次性添加本月份的所有开料员绩效考核的)
        //删除开料员的绩效奖金和组长、主管的绩效奖金
        Integer month = jxAssessPzcjs.get(0).getAssessMonth();
        Integer year = jxAssessPzcjs.get(0).getAssessYear();
        deleteJxAssessPzcjEmp(assessType,year,month);
        deleteJxAssessPzcjEmp(assessType2,year,month);
        //插入开料员绩效考核数据
        for (JxAssessPzcj jxAssess : jxAssessPzcjs) {
            jxAssess.setAssessType(assessType); //1、开料员绩效考核资料
            String resultMoney = jxAssess.getResultMoney();
            //判断开料员是否有最终绩效奖金
            if (resultMoney.equals("NaN")) {
                throw new JxAssessException(WSC.PRECONDITIONFAILED, JxConst.SUBMIT_EFEATED_ILLEGALITY_DATA);
            }
            this.addJxAssessPzcj(jxAssess);
        }
        //保存最终综合绩效奖金统计
        this.addJxAssessTotal(jxAssessPzcjReception,month,year,assessType);
        return jxAssessPzcjs;
    }

    private List<JxEmp> addKaiLiaoYuanAssessDataGetJxEmps(List<JxAssessPzcj> jxAssessPzcjs,String postName) {
        String assessDept = jxAssessPzcjs.get(0).getAssessDept();
        List<Long> postIds=new ArrayList<>();
        JxPost jxPost = new JxPost();
        jxPost.setPkDept(assessDept);
        jxPost.setName(postName); //开料管理人员或培训组长
        //根据岗位名称和部门代码查询出当前的人员信息
        List<JxPost> rJxPosts = jxPostService.getJxPostBycondition(jxPost);

        //根据岗位信息的id查询是否有下一层的职位人员：开料管理人员：当前只有主管、技术组长
        JxPost j = rJxPosts.get(0);
        jxPost.setPid(j.getId());
        jxPost.setPkDept(null);
        jxPost.setName(null);
        List<JxPost> ps= jxPostService.getJxPostBycondition(jxPost);
        //查询若没有值,证明是没有下级人员
        if(ps.size()>0){
            ps.stream().forEach(b->postIds.add(b.getId()));
        }else {
            postIds.add(j.getId()); //培训组长没有下级岗位id
        }

        //最终根据部门代码和岗位id(唯一性)查询最后的人员信息
        return jxEmpService.selectJxEmpByPkDeptAndPostIds(assessDept,postIds);
    }

    private void addKaiLiaoYuanAssessDataAddManagerData(JxAssessReception jxAssessPzcjReception, List<JxAssessPzcj> jxAssessPzcjs, List<JxEmp> jxEmps, Integer assessType) {
        //封装年、月、部门数据
        JxAssessPzcj jx=  packagingJxAssessPzcj(jxAssessPzcjs);

        //绩效奖金管理人员的插入：主管、组长的平均班组总绩效奖金和班组平均绩效奖金
        //获取前端的统计信息：1、A组平均成绩、2、B组平均成绩、3、全部合计暂时不管它
        List<Map<String, String>> managers = jxAssessPzcjReception.getMaps();
        managers.stream().forEach((map)->{
            String empCodeContent = map.get("empCode"); //A组平均绩效成绩，B组平均绩效成绩.....
            for (JxEmp emp : jxEmps) {
                String empGroup = emp.getEmpGroup();  //获取员工班组
                if (!StringUtils.isBlank(empGroup)){
                    if (empCodeContent.contains(empGroup)){ //判断班组：添加每组的平均绩效成绩
                        jx.setTeamAvgBonus(map.get("resultMoney"));  //平均成绩
                        jx.setTeamTotalBonus(map.get("groupTotalBonus"));   //班组总奖金
                        jx.setEmpName(emp.getEmpName());    //封装人员姓名
                        jx.setEmpCode(emp.getEmpCode());    //封装工号
                        jx.setEmpGroup(empGroup);             //封装班组
                        jx.setPostName(emp.getPostName());  //岗位名称
                        jx.setAssessType(assessType); //3、管理人员表的考核类型、
                        //插入管理人员绩效考核表中
                        this.addJxAssessPzcj(jx);
                    }
                }
            }
        });
    }
    //添加合计表中的数据
    private void addJxAssessTotal(JxAssessReception jxAssessPzcjReception, Integer month, Integer year,Integer assessType) {
        List<Map<String, String>> maps = jxAssessPzcjReception.getMaps();
        for (Map<String,String> map:maps){
            String resultMoney = map.get("resultMoney");//最终绩效奖金
            String name = map.get("empCode");//键的名称：如开料员有：1、合计、2、A组平均绩效奖金、3、B组平均绩效奖金。。。
            JxAssessTotal jxAssessTotal = new JxAssessTotal();
            jxAssessTotal.setAssessType(assessType);    //绩效类型--开料员的数据类型
            jxAssessTotal.setAssessYear(year);
            jxAssessTotal.setAssessMonth(month);
            jxAssessTotal.setTotalMoney(resultMoney);
            jxAssessTotal.setRemarks(name);                     //备注
            jxAssessTotalService.insertSelective(jxAssessTotal);
        }
    }

}
